// AutoPowerOnShutdownDlg.cpp : implementation file
//

#include "stdafx.h"
#include "AutoPowerOnShutdown.h"
#include "AutoPowerOnShutdownDlg.h"
#include <Mmsystem.h>
#include <Shlwapi.h>
#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <comdef.h>
#include <Wbemidl.h>
#pragma comment (lib, "comsuppw.lib") 
# pragma comment(lib, "wbemuuid.lib")

#pragma warning(disable:4482 4996)
#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CAutoPowerOnShutdownDlg dialog

CAutoPowerOnShutdownDlg::CAutoPowerOnShutdownDlg(CWnd* pParent /*=NULL*/)
: CDialog(CAutoPowerOnShutdownDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_LONGRUN);

}

void CAutoPowerOnShutdownDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_STATIC_DRAW_CLOCK, m_StaticClock);
	DDX_Control(pDX, IDC_DATETIMEPICKER_SPEC, m_DateTime);
	DDX_Control(pDX, IDC_EDIT_COUNT, m_EditCount);
	DDX_Control(pDX, IDC_COMBO_UNIT, m_CombUnit);
	DDX_Control(pDX, IDC_EDIT_LOOPNUM, m_EditLoop);
	DDX_Control(pDX, IDC_STATIC_LOOPS, m_StaticLoop);
	DDX_Control(pDX, IDC_CHECK_AUTORUN, m_BtnSetAutoRun);
}

BEGIN_MESSAGE_MAP(CAutoPowerOnShutdownDlg, CDialog)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_BN_CLICKED(IDC_RESET, &CAutoPowerOnShutdownDlg::OnBnClickedReset)
	ON_BN_CLICKED(IDC_APPLY, &CAutoPowerOnShutdownDlg::OnBnClickedApply)
	ON_BN_CLICKED(IDC_BUTTON_SHUTDOWN, &CAutoPowerOnShutdownDlg::OnBnClickedButtonShutdown)
	ON_BN_CLICKED(IDC_BUTTON_REBOOT, &CAutoPowerOnShutdownDlg::OnBnClickedButtonReboot)
	ON_BN_CLICKED(IDC_BUTTON_LOGOFF, &CAutoPowerOnShutdownDlg::OnBnClickedButtonLogoff)
	ON_BN_CLICKED(IDC_BUTTON_HIBERNATE, &CAutoPowerOnShutdownDlg::OnBnClickedButtonHibernate)
	ON_MESSAGE(WM_NOTIFYICON, OnNotifyIcon)
	ON_WM_SYSCOMMAND()
	ON_WM_DESTROY()
	ON_BN_CLICKED(IDC_RADIO_COUNTDOWN, &CAutoPowerOnShutdownDlg::OnBnClickedRadioCountdown)
	ON_BN_CLICKED(IDC_RADIO_SPECTIME, &CAutoPowerOnShutdownDlg::OnBnClickedRadioSpectime)
	ON_BN_CLICKED(IDC_CHECK_AUTORUN, &CAutoPowerOnShutdownDlg::OnBnClickedCheckAutorun)
	ON_BN_CLICKED(IDC_RADIOS3, &CAutoPowerOnShutdownDlg::OnBnClickedRadios3)
	ON_BN_CLICKED(IDC_RADIOS4, &CAutoPowerOnShutdownDlg::OnBnClickedRadios4)
	ON_BN_CLICKED(IDC_RADIOS5, &CAutoPowerOnShutdownDlg::OnBnClickedRadios5)
END_MESSAGE_MAP()


// CAutoPowerOnShutdownDlg message handlers

BOOL CAutoPowerOnShutdownDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	
	// show digital clock
	m_StaticClock.Start(IDB_CLOCKST_PANE, IDB_CLOCKST_BIG, IDB_CLOCKST_SMALL);


	//check ini file is exist or not
	if(!IsIniFileExist())
	{
		//if autorun not set 
		//create ini file
		CreateDefaultIniFile();
	}

	//Set the controls' state through 
	//ini file
	InitFromIniFle();

	//go go go!!!
	GoByCondition();

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CAutoPowerOnShutdownDlg::GoByCondition(void)
{
	if(m_DlInf.m_ILoops > 0 && ((CButton*)GetDlgItem(IDC_RADIO_COUNTDOWN))->GetCheck() == BST_CHECKED )
	{
		ActionGo();

	}
	else
	{
		;//InitFromIniFle();		
	}
}
// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CAutoPowerOnShutdownDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}


}

// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CAutoPowerOnShutdownDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}

void CAutoPowerOnShutdownDlg::OnBnClickedReset()
{
	InitFromIniFle();
	this->SetS4WakeTimer(20);
}

void CAutoPowerOnShutdownDlg::OnBnClickedApply()
{
	GetDelayInfo();
	if(m_DlInf.m_TimeSnd < 0)
	{
		MessageBox(_T("The Delay Time Is Evil!"),_T("Evil Time"),MB_OK);
		return;
	}
	if(((CButton*)GetDlgItem(IDC_RADIO_COUNTDOWN))->GetCheck() == BST_CHECKED
		&& m_DlInf.m_ILoops < 1)
	{
		MessageBox(_T("The Loops Count Is Evil!"),_T("Evil Loop Num"),MB_OK);
		return;
	}

	ActionGo();

	//hide window and show in tray
	ShowWindow(SW_HIDE);	
	Add2Tray();
}

void CAutoPowerOnShutdownDlg::SetS4WakeTimer(unsigned char seconds)
{
	HRESULT hres;

    // Step 1: --------------------------------------------------
    // Initialize COM. ------------------------------------------

    hres =  CoInitializeEx(0, COINIT_MULTITHREADED); 
    if (FAILED(hres))
    {
        cout << "Failed to initialize COM library. Error code = 0x" 
            << hex << hres << endl;
		return;
    }

    // Step 2: --------------------------------------------------
    // Set general COM security levels --------------------------
    // Note: If you are using Windows 2000, you need to specify -
    // the default authentication credentials for a user by using
    // a SOLE_AUTHENTICATION_LIST structure in the pAuthList ----
    // parameter of CoInitializeSecurity ------------------------

    hres =  CoInitializeSecurity(
        NULL, 
        -1,                          // COM authentication
        NULL,                        // Authentication services
        NULL,                        // Reserved
        RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication 
        RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  
        NULL,                        // Authentication info
        EOAC_NONE,                   // Additional capabilities 
        NULL                         // Reserved
        );

                      
    if (FAILED(hres))
    {
        cout << "Failed to initialize security. Error code = 0x" 
            << hex << hres << endl;
        CoUninitialize();
		return;
    }
    
    // Step 3: ---------------------------------------------------
    // Obtain the initial locator to WMI -------------------------

    IWbemLocator *pLoc = NULL;

    hres = CoCreateInstance(
        CLSID_WbemLocator,             
        0, 
        CLSCTX_INPROC_SERVER, 
        IID_IWbemLocator, (LPVOID *) &pLoc);
 
    if (FAILED(hres))
    {
        cout << "Failed to create IWbemLocator object."
            << " Err code = 0x"
            << hex << hres << endl;
        CoUninitialize();
        return ;                 // Program has failed.
    }

    // Step 4: -----------------------------------------------------
    // Connect to WMI through the IWbemLocator::ConnectServer method

    IWbemServices *pSvc = NULL;
	
    // Connect to the root\cimv2 namespace with
    // the current user and obtain pointer pSvc
    // to make IWbemServices calls.
    hres = pLoc->ConnectServer(
         _bstr_t(L"ROOT\\WMI"), // Object path of WMI namespace
         NULL,                    // User name. NULL = current user
         NULL,                    // User password. NULL = current
         0,                       // Locale. NULL indicates current
         NULL,                    // Security flags.
         0,                       // Authority (e.g. Kerberos)
         0,                       // Context object 
         &pSvc                    // pointer to IWbemServices proxy
         );
    
    if (FAILED(hres))
    {
        cout << "Could not connect. Error code = 0x" 
             << hex << hres << endl;
        pLoc->Release();     
        CoUninitialize();
        return ;                // Program has failed.
    }

    cout << "Connected to ROOT\\CIMV2 WMI namespace" << endl;


    // Step 5: --------------------------------------------------
    // Set security levels on the proxy -------------------------

    hres = CoSetProxyBlanket(
       pSvc,                        // Indicates the proxy to set
       RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
       RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
       NULL,                        // Server principal name 
       RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx 
       RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
       NULL,                        // client identity
       EOAC_NONE                    // proxy capabilities 
    );

    if (FAILED(hres))
    {
        cout << "Could not set proxy blanket. Error code = 0x" 
            << hex << hres << endl;
        pSvc->Release();
        pLoc->Release();     
        CoUninitialize();
        return ;               // Program has failed.
    }

    // Step 6: --------------------------------------------------
    // Use the IWbemServices pointer to make requests of WMI ----

    // For example, get the name of the operating system
    IEnumWbemClassObject* pEnumerator = NULL;
    hres = pSvc->ExecQuery(
        bstr_t("WQL"), 
        bstr_t("SELECT * FROM MSI_System"),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
        NULL,
        &pEnumerator);
    
    if (FAILED(hres))
    {
        cout << "Query for operating system name failed."
            << " Error code = 0x" 
            << hex << hres << endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return;               // Program has failed.
    }

    // Step 7: -------------------------------------------------
    // Get the data from the query in step 6 -------------------
 
    IWbemClassObject *pclsObj;
    ULONG uReturn = 0;
    int count = 0;
    while (pEnumerator)
    {
        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, 
            &pclsObj, &uReturn);

        if(0 == uReturn)
        {
            break;
        }

		if(++count == 3)
		{
			CString tmp;
			tmp.Format(_T("%d"),seconds);
  			// Set up the property value.
			VARIANT v; 
			VariantInit(&v);
			V_VT(&v) = VT_BSTR;
			V_BSTR(&v) = tmp.AllocSysString(); // - decimal format, not hex

			hr = pclsObj->Put(L"System",0,&v,CIM_UINT8);
			// Clean up.
			VariantClear(&v);
			
			if (hr == WBEM_E_ACCESS_DENIED)
			{
				printf("WBEM_E_ACCESS_DENIED\n");

				// Processing to handle specific error code
			}
			else if (hr == WBEM_S_DUPLICATE_OBJECTS)
			{
				printf("WBEM_S_DUPLICATE_OBJECTS\n");
				// All other cases, including errors specific to COM
			}
			else if (hr == WBEM_E_INVALID_OBJECT)
			{
				printf("WBEM_E_INVALID_OBJECT\n");
			}
			else if(hr == WBEM_E_INVALID_PARAMETER)
			{
				printf("WBEM_E_INVALID_PARAMETER\n");
			}
			else if(hr == WBEM_S_NO_ERROR)
			{
				printf("WBEM_S_NO_ERROR\n");
			}
			else 
				printf("ERROR:%x",hr);

			HRESULT hRes = pSvc->PutInstance(pclsObj,WBEM_FLAG_CREATE_OR_UPDATE,0,0);
			
			// Check for specific error and status codes.
			if (hRes == WBEM_E_ACCESS_DENIED)
			{
				printf("WBEM_E_ACCESS_DENIED\n");

				// Processing to handle specific error code
			}
			else if (hRes == WBEM_S_DUPLICATE_OBJECTS)
			{
				printf("WBEM_S_DUPLICATE_OBJECTS\n");
				// All other cases, including errors specific to COM
			}
			else if (hRes == WBEM_E_INVALID_OBJECT)
			{
				printf("WBEM_E_INVALID_OBJECT\n");
			}
			else if(hRes == WBEM_E_INVALID_PARAMETER)
			{
				printf("WBEM_E_INVALID_PARAMETER\n");
			}
			else if(hRes == WBEM_S_NO_ERROR)
			{
				printf("WBEM_S_NO_ERROR\n");
			}
		}

    }

    // Cleanup
    // ========
    
    pSvc->Release();
    pLoc->Release();
    pEnumerator->Release();
    pclsObj->Release();
    CoUninitialize();	
}

void CAutoPowerOnShutdownDlg::ActionGo(void)
{
	switch(m_DlInf.m_Act)
	{
	case ACTION::S3:
		{
			SavePar2IniFile();
			SetPower(TRUE,FALSE);
		}
		break;

	case ACTION::S4:
		{
			SavePar2IniFile();
			SetPower(FALSE,FALSE);
		}
		break;
	
	case ACTION::S5:
		{
			SavePar2IniFile();	
			SetS4WakeTimer(m_DlInf.m_TimeSnd);
			ExitWindow(EWX_SHUTDOWN);
		}
		break;

	}
}

void CAutoPowerOnShutdownDlg::GetDelayInfo(void)
{
	if(((CButton*)GetDlgItem(IDC_RADIOS3))->GetCheck() == BST_CHECKED)
	{
		this->m_DlInf.m_Act = ACTION::S3;	
	}
	else if(((CButton*)GetDlgItem(IDC_RADIOS4))->GetCheck() == BST_CHECKED)
	{
		this->m_DlInf.m_Act = ACTION::S4;
	}
	else if(((CButton*)GetDlgItem(IDC_RADIOS5))->GetCheck() == BST_CHECKED)
	{
		this->m_DlInf.m_Act = ACTION::S5;
	}

	if(((CButton*)GetDlgItem(IDC_RADIO_SPECTIME))->GetCheck() == BST_CHECKED)
	{
		this->m_DlInf.m_Par = TIMEPARTYPE::SPECTIME;
		this->m_DlInf.m_TimeSnd = GetSpecTime();
		this->m_DlInf.m_Unit = TIMEUNIT::SECOND;
	}
	else if(((CButton*)GetDlgItem(IDC_RADIO_COUNTDOWN))->GetCheck() == BST_CHECKED)
	{
		this->m_DlInf.m_Par = TIMEPARTYPE::COUNTDOWN;
		this->m_DlInf.m_TimeSnd = GetCountDownTime();
		this->m_DlInf.m_Unit =(TIMEUNIT)(m_CombUnit.GetCurSel() + 1);
		
		CString tmp;
		m_EditLoop.GetWindowTextW(tmp);
		this->m_DlInf.m_ILoops = _wtoi(tmp);
	}
}

int CAutoPowerOnShutdownDlg::GetSpecTime()
{
	int  seconds;
	int iSetHour;
	int iCurHour;
	CTime tme;
	CTime curTm = CTime::GetCurrentTime();
	m_DateTime.GetTime(tme);
	if(tme.GetHour() == 0)
		iSetHour = 24;
	if(curTm.GetHour() == 0)
		iCurHour = 24;
	seconds = (tme.GetHour() - curTm.GetHour()) * 3600 
		+ (tme.GetMinute()-curTm.GetMinute()) * 60
		+ (tme.GetSecond() - curTm.GetSecond());
	return seconds;
}

int CAutoPowerOnShutdownDlg::GetCountDownTime()
{
	int seconds;
	CString tmp;
	m_EditCount.GetWindowTextW(tmp);
	switch(this->m_CombUnit.GetCurSel())
	{
	case 0:
		seconds = _wtoi(tmp.GetBuffer());
		break;
	case 1:
		seconds = (_wtoi(tmp.GetBuffer()))*60;
		break;
	case 2:
		seconds = (_wtoi(tmp.GetBuffer()))*3600;
		break;
	}
	return seconds;
}

void CAutoPowerOnShutdownDlg::OnBnClickedButtonShutdown()
{
	if( MessageBox(_T("Sure to Shutdown the Windows?"),_T("Shutdown"),MB_OKCANCEL)
		== IDCANCEL)
		return;

	ExitWindow(EWX_SHUTDOWN);
}

void CAutoPowerOnShutdownDlg::OnBnClickedButtonReboot()
{
	if( MessageBox(_T("Sure to Reboot the Windows?"),_T("Reboot"),MB_OKCANCEL)
		== IDCANCEL)
		return;

	ExitWindow(EWX_REBOOT);
}

void CAutoPowerOnShutdownDlg::OnBnClickedButtonLogoff()
{
	if( MessageBox(_T("Sure to Logoff the Windows?"),_T("LogOff"),MB_OKCANCEL)
		== IDCANCEL)
		return;

	ExitWindow(EWX_LOGOFF);
}

void CAutoPowerOnShutdownDlg::OnBnClickedButtonHibernate()
{
	if( MessageBox(_T("Sure to Hibernate the Windows?"),_T("Hibernate"),MB_OKCANCEL)
		== IDCANCEL)
		return;
	SetPower(FALSE,TRUE);
}

void CAutoPowerOnShutdownDlg::HideLoops(BOOL bHide)
{
	if(bHide)
	{
		m_EditLoop.ShowWindow(SW_HIDE);
		m_StaticLoop.ShowWindow(SW_HIDE);
	}
	else
	{
		m_EditLoop.ShowWindow(SW_SHOW);
		m_StaticLoop.ShowWindow(SW_SHOW);
	}
}

void CAutoPowerOnShutdownDlg::InitFromIniFle(void)
{
	//get DelayInfo from ini file 
	ReadIni(m_DlInf);

	CString tmp;
	tmp.Format(L"%d",m_DlInf.m_ILoops);
	m_EditLoop.SetWindowTextW(tmp);
	
	m_CombUnit.ResetContent();
	m_CombUnit.InsertString(0,CString(_T("Second")));
	m_CombUnit.InsertString(1,CString(_T("Minute")));
	m_CombUnit.InsertString(2,CString(_T("Hour")));
	m_CombUnit.SetCurSel(m_DlInf.m_Unit-1);

	if(m_DlInf.m_Unit == TIMEUNIT::SECOND)
	{
		tmp.Format(L"%d",m_DlInf.m_TimeSnd);
		m_EditCount.SetWindowTextW(tmp);
	}
	else if(m_DlInf.m_Unit == TIMEUNIT::MINUTE)
	{
		tmp.Format(L"%d",m_DlInf.m_TimeSnd/60);
		m_EditCount.SetWindowTextW(tmp);
	}
	else
	{	
		tmp.Format(L"%d",m_DlInf.m_TimeSnd/3600);
		m_EditCount.SetWindowTextW(tmp);
	}

	if(m_DlInf.m_Act == ACTION::S3)
	{
		((CButton*)GetDlgItem(IDC_RADIOS3))->SetCheck(TRUE);
	}
	else if(m_DlInf.m_Act == ACTION::S4)
	{
		((CButton*)GetDlgItem(IDC_RADIOS4))->SetCheck(TRUE);
	}
	else if(m_DlInf.m_Act == ACTION::S5)
	{
		((CButton*)GetDlgItem(IDC_RADIOS5))->SetCheck(TRUE);
	}

	((CButton*)GetDlgItem(IDC_RADIO_SPECTIME))->SetCheck(FALSE);
	((CButton*)GetDlgItem(IDC_RADIO_COUNTDOWN))->SetCheck(FALSE);
	
	if(m_DlInf.m_Par == TIMEPARTYPE::SPECTIME)
	{
		((CButton*)GetDlgItem(IDC_RADIO_SPECTIME))->SetCheck(TRUE);
		HideLoops(TRUE);
	}
	else
	{
		((CButton*)GetDlgItem(IDC_RADIO_COUNTDOWN))->SetCheck(TRUE);
		HideLoops(FALSE);
	}


	((CButton*)GetDlgItem(IDC_CHECK_AUTORUN))->SetCheck(IsAutoRunExit());

}
void CAutoPowerOnShutdownDlg::ReadIni(DelayInfo& dlInf)
{
	CString csAction;
	GetPrivateProfileString (L"UserConfig", 
		L"UserAction", 
		L"UserAction", 
		csAction.GetBuffer(MAX_PATH), 
		MAX_PATH, 
		L"AutoPowerOnShutdownConfig.ini");

	CString csTmType;
	GetPrivateProfileString (L"UserConfig", 
		L"TimeParType", 
		L"TimeParType", 
		csTmType.GetBuffer(MAX_PATH), 
		MAX_PATH, 
		L"AutoPowerOnShutdownConfig.ini");
	CString csTmUnit;
	GetPrivateProfileString (L"UserConfig", 
		L"TimeUnit", 
		L"TimeUnit", 
		csTmUnit.GetBuffer(MAX_PATH), 
		MAX_PATH, 
		L"AutoPowerOnShutdownConfig.ini");
	CString csDelayTm;
	GetPrivateProfileString (L"UserConfig", 
		L"DelayTime", 
		L"DelayTime", 
		csDelayTm.GetBuffer(MAX_PATH), 
		MAX_PATH, 
		L"AutoPowerOnShutdownConfig.ini");

	CString csActionLoops;
	GetPrivateProfileString (L"UserConfig", 
		L"ActionLoops", 
		L"ActionLoops", 
		csActionLoops.GetBuffer(MAX_PATH), 
		MAX_PATH, 
		L"AutoPowerOnShutdownConfig.ini");

	int iAction = _wtoi(csAction);
	int iTmType = _wtoi(csTmType);
	int iTmUnit = _wtoi(csTmUnit);
	int iDelayTm = _wtoi(csDelayTm);
	int iActionLoops = _wtoi(csActionLoops);

	dlInf.m_Act = (ACTION)iAction;
	dlInf.m_Unit = (TIMEUNIT)iTmUnit;
	dlInf.m_ILoops = iActionLoops;
	dlInf.m_Par = (TIMEPARTYPE)iTmType;
	dlInf.m_TimeSnd = iDelayTm;


}

void CAutoPowerOnShutdownDlg::ExitWindow(int CMDID)
{
	HANDLE hdl;  
	OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hdl);  
	PTOKEN_PRIVILEGES ptoken = (PTOKEN_PRIVILEGES) new BYTE[sizeof(DWORD) +  
		sizeof(LUID_AND_ATTRIBUTES)];  
	ptoken->PrivilegeCount = 1;  
	LUID uid;  
	LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &uid); 
	ptoken->Privileges[0].Luid = uid;  
	ptoken->Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;  
	AdjustTokenPrivileges(hdl, FALSE, ptoken, 0, NULL, NULL);
	CloseHandle(hdl);  
	delete [](BYTE *)ptoken; 

	//Sleep(100);
	ExitWindowsEx(CMDID|EWX_FORCE,0);	
}

//hibernate and standby
int	CAutoPowerOnShutdownDlg::SetPower(BOOL   bSuspend,BOOL   bForce)
{             
	TOKEN_PRIVILEGES   tp;           
	HANDLE   hToken;   
	LUID   luid;   
	LPTSTR   MachineName=NULL;     

	if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken   ))   
	{   
		return   RTN_ERROR;   
	}   
	if(!LookupPrivilegeValue(MachineName,   SE_SHUTDOWN_NAME,   &luid))   
	{   
		return   RTN_ERROR;   
	}   
	tp.PrivilegeCount   =   1;   
	tp.Privileges[0].Luid   =   luid;   
	tp.Privileges[0].Attributes   =   SE_PRIVILEGE_ENABLED;   
	AdjustTokenPrivileges(hToken,   FALSE,   &tp,   sizeof(TOKEN_PRIVILEGES),NULL,   NULL   );   
	SetSystemPowerState(bSuspend,bForce);   

	return   0;   
}   


LRESULT CAutoPowerOnShutdownDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	switch(message)   
	{   
	case   WM_POWERBROADCAST:   
		switch(wParam)   
		{   
			//wake up 
		case   PBT_APMSUSPEND:  
			{

				HANDLE hTimer=::CreateWaitableTimer(NULL,TRUE,CString(_T("WaitForResume")));   
				if(!hTimer)   
				{   
					MessageBox(CString(_T("Fail   to   create   waitable   timer!")));    
				}   
				hTimer=OpenWaitableTimer(TIMER_ALL_ACCESS,TRUE,CString(_T("WaitForResume")));   
				LARGE_INTEGER   liDueTime;   
				liDueTime.QuadPart=m_DlInf.m_TimeSnd *1000*1000*(-10);   
				if(!::SetWaitableTimer(hTimer,&liDueTime,0,NULL,NULL,TRUE))   
				{   
					MessageBox(CString(_T("Fail   to   set   waitable   timer!")));   
					break;   
				}   
			}
			break;
		
		case PBT_APMRESUMEAUTOMATIC:
			{
				
				DelFromTray();

				ShowWindow(SW_SHOW);

				//Set the controls' state through 
				//ini file
				InitFromIniFle();

				//go go go!!!
				GoByCondition();
			}
			break;
		default:   
			break;     
		}

	default:   
		break;   

	}   

	return CDialog::WindowProc(message, wParam, lParam);
}

void CAutoPowerOnShutdownDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if (nID == SC_MAXIMIZE)
		return;
	if (nID == SC_MINIMIZE)
	{
		ShowWindow(SW_HIDE);
		AnimateWindow(1000,AW_HIDE|AW_BLEND);
		Add2Tray();
	}
	else
		CDialog::OnSysCommand(nID, lParam);
}

LRESULT CAutoPowerOnShutdownDlg::OnNotifyIcon(WPARAM wParam, LPARAM lParam)
{
	if ((wParam == 0x5)&&(lParam == WM_LBUTTONDOWN))
	{
		ShowWindow(SW_SHOWNORMAL);
		DelFromTray();	
	}
	return 0;
}

void CAutoPowerOnShutdownDlg::Add2Tray(void)
{
	m_nd.cbSize	= sizeof (NOTIFYICONDATA);
	m_nd.hWnd	= m_hWnd;
	m_nd.uID	= 0x5;
	m_nd.uFlags	= NIF_ICON|NIF_MESSAGE|NIF_TIP;
	m_nd.uCallbackMessage	= WM_NOTIFYICON;
	m_nd.hIcon	= m_hIcon;
	wcscpy(m_nd.szTip, L"AutoPowerOnShutDown");
	Shell_NotifyIcon(NIM_ADD, &m_nd);
}

void CAutoPowerOnShutdownDlg::DelFromTray(void)
{
	m_nd.cbSize = sizeof (NOTIFYICONDATA);
	m_nd.hWnd = m_hWnd;

	m_nd.uID = 0x5;
	m_nd.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP;
	m_nd.uCallbackMessage = WM_NOTIFYICON;
	m_nd.hIcon = m_hIcon;

	Shell_NotifyIcon(NIM_DELETE, &m_nd);
}
void CAutoPowerOnShutdownDlg::OnDestroy()
{

	/* if(!IsWindowVisible())*/
	DelFromTray();

	CDialog::OnDestroy();
}

void CAutoPowerOnShutdownDlg::SavePar2IniFile()
{
	//this->GetDelayInfo();

	//not in interval time mode loops will be < -1 so...
	if(m_DlInf.m_ILoops > 0)
		this->m_DlInf.m_ILoops -= 1;

	CString tmp;
	WritePrivateProfileStringW( NULL, NULL, NULL, L"AutoPowerOnShutdownConfig.ini" ); 

	tmp.Format(L"%d",m_DlInf.m_Act);
	WritePrivateProfileString (L"UserConfig", 
		L"UserAction", 
		tmp, 
		L"AutoPowerOnShutdownConfig.ini"); 

	tmp.Format(L"%d",m_DlInf.m_Par);
	WritePrivateProfileString (L"UserConfig", 
		L"TimeParType", 
		tmp, 
		L"AutoPowerOnShutdownConfig.ini"); 

	tmp.Format(L"%d",m_DlInf.m_Unit);
	WritePrivateProfileString (L"UserConfig", 
		L"TimeUnit", 
		tmp, 
		L"AutoPowerOnShutdownConfig.ini"); 

	tmp.Format(L"%d",m_DlInf.m_TimeSnd);
	WritePrivateProfileString (L"UserConfig", 
		L"DelayTime", 
		tmp, 
		L"AutoPowerOnShutdownConfig.ini");

	tmp.Format(L"%d",m_DlInf.m_ILoops);
	WritePrivateProfileString (L"UserConfig", 
		L"ActionLoops", 
		tmp, 
		L"AutoPowerOnShutdownConfig.ini");
}

void CAutoPowerOnShutdownDlg::CreateDefaultIniFile()
{
	WritePrivateProfileStringW( NULL, NULL, NULL, L"AutoPowerOnShutdownConfig.ini" ); 

	WritePrivateProfileString (L"UserConfig", 
		L"UserAction", 
		L"1", 
		L"AutoPowerOnShutdownConfig.ini"); 

	WritePrivateProfileString (L"UserConfig", 
		L"TimeParType", 
		L"1", 
		L"AutoPowerOnShutdownConfig.ini"); 

	WritePrivateProfileString (L"UserConfig", 
		L"TimeUnit", 
		L"1", 
		L"AutoPowerOnShutdownConfig.ini"); 

	WritePrivateProfileString (L"UserConfig", 
		L"DelayTime", 
		L"100", 
		L"AutoPowerOnShutdownConfig.ini");

	WritePrivateProfileString (L"UserConfig", 
		L"ActionLoops", 
		L"1", 
		L"AutoPowerOnShutdownConfig.ini");
}

void CAutoPowerOnShutdownDlg::OnBnClickedRadioCountdown()
{
	HideLoops(FALSE);
}

void CAutoPowerOnShutdownDlg::OnBnClickedRadioSpectime()
{
	HideLoops(TRUE);
}

void CAutoPowerOnShutdownDlg::OnBnClickedCheckAutorun()
{	
	if(m_BtnSetAutoRun.GetCheck() == BST_CHECKED)//set auto run	
	{
		IsAutoRunExit()?
NULL:SetAutoRun(GetMyPath());
	}
	else//remove auto run
	{
		RemoveAutoRun(GetMyPath());
	}
}

BOOL CAutoPowerOnShutdownDlg::RemoveAutoRun(CString cstrApp)
{
	CString str;
	HKEY hRegKey;
	BOOL bResult;
	str=_T("Software\\Microsoft\\Windows\\CurrentVersion\\Run");
	if(RegOpenKey(HKEY_LOCAL_MACHINE, str, &hRegKey) != ERROR_SUCCESS) 
		bResult=FALSE;
	else
	{
		_wsplitpath(cstrApp.GetBuffer(0),NULL,NULL,str.GetBufferSetLength(MAX_PATH+1),NULL);
		cstrApp.ReleaseBuffer();
		str.ReleaseBuffer();
		if(::RegDeleteValue(hRegKey,str) != ERROR_SUCCESS)
			bResult = FALSE;
		else
			bResult=TRUE;
		cstrApp.ReleaseBuffer();
	}
	return bResult;
}

BOOL CAutoPowerOnShutdownDlg::IsAutoRunExit()
{	
	CString strPath = GetMyPath();
	CString str;
	HKEY hRegKey;
	BOOL bResult;
	str=_T("Software\\Microsoft\\Windows\\CurrentVersion\\Run");
	if(RegOpenKey(HKEY_LOCAL_MACHINE, str, &hRegKey) != ERROR_SUCCESS) 
		bResult=FALSE;
	else
	{
		_wsplitpath(strPath.GetBuffer(0),NULL,NULL,str.GetBufferSetLength(MAX_PATH+1),NULL);
		strPath.ReleaseBuffer();
		str.ReleaseBuffer();

		TCHAR sz[256];
		CString cstrTmp;
		DWORD dwtype, sl = 256 * sizeof(TCHAR); 

		if(RegQueryValueEx(hRegKey,str,NULL,&dwtype,(LPBYTE)sz, (LPDWORD)&sl)==ERROR_SUCCESS)
		{

			CString tmp1(sz);
			tmp1.Trim().MakeUpper();
			CString tmp2 = strPath.MakeUpper();
			if(tmp1 == tmp2)
				bResult=TRUE;
			else
			{
				bResult=FALSE;
				::RegDeleteValue(hRegKey,str); 
			}

		}
		else
		{
			bResult=FALSE;
		}
		strPath.ReleaseBuffer();
	}

	return bResult;	
}

BOOL  CAutoPowerOnShutdownDlg::SetAutoRun(CString strPath)
{
	CString str;
	HKEY hRegKey;
	BOOL bResult;
	str=_T("Software\\Microsoft\\Windows\\CurrentVersion\\Run");
	if(RegOpenKey(HKEY_LOCAL_MACHINE, str, &hRegKey) != ERROR_SUCCESS) 
		bResult=FALSE;
	else
	{
		_wsplitpath(strPath.GetBuffer(0),NULL,NULL,str.GetBufferSetLength(MAX_PATH+1),NULL);
		strPath.ReleaseBuffer();
		str.ReleaseBuffer();
		if(::RegSetValueEx( hRegKey,
			str,
			0,
			REG_SZ,
			(const BYTE*)strPath.GetBuffer(0),
			(strPath.GetLength()) * sizeof(TCHAR) ) != ERROR_SUCCESS)
			bResult=FALSE;
		else
			bResult=TRUE;
		strPath.ReleaseBuffer();
	}
	return bResult;

}

CString CAutoPowerOnShutdownDlg::GetMyPath()
{

	CString strPath;
	GetModuleFileName(NULL,strPath.GetBufferSetLength(MAX_PATH+1),MAX_PATH);
	strPath.ReleaseBuffer();
	return strPath;

}

BOOL CAutoPowerOnShutdownDlg::IsIniFileExist()
{
#define INFO_BUFFER_SIZE 32767
	TCHAR  infoBuf[INFO_BUFFER_SIZE];
	// Get and display the system directory. 
	if( !GetWindowsDirectory( infoBuf, INFO_BUFFER_SIZE ) )
		return FALSE;
	CString absStrPath(infoBuf);
	absStrPath.Append(L"\\AutoPowerOnShutdownConfig.ini");

	return PathFileExists(absStrPath);

}
void CAutoPowerOnShutdownDlg::OnBnClickedRadios3()
{
	m_DlInf.m_Act = ACTION::S3;
}

void CAutoPowerOnShutdownDlg::OnBnClickedRadios4()
{
	m_DlInf.m_Act = ACTION::S4;
}

void CAutoPowerOnShutdownDlg::OnBnClickedRadios5()
{
	m_DlInf.m_Act = ACTION::S5;
}
